package org.jeecg.modules.designer.controller;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StreamUtils;
import org.apache.commons.lang.StringUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.TokenUtils;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.bpm.service.impl.ActProcessService;
import org.jeecg.modules.extbpm.process.common.WorkFlowGlobals;
import org.jeecg.modules.extbpm.process.entity.ExtActExpression;
import org.jeecg.modules.extbpm.process.entity.ExtActListener;
import org.jeecg.modules.extbpm.process.entity.ExtActProcess;
import org.jeecg.modules.extbpm.process.entity.ExtActProcessNode;
import org.jeecg.modules.extbpm.process.pojo.ListenerInfo;
import org.jeecg.modules.extbpm.process.pojo.RoleInfo;
import org.jeecg.modules.extbpm.process.pojo.UserInfo;
import org.jeecg.modules.extbpm.process.service.IExtActExpressionService;
import org.jeecg.modules.extbpm.process.service.IExtActListenerService;
import org.jeecg.modules.extbpm.process.service.IExtActProcessNodeService;
import org.jeecg.modules.extbpm.process.service.IExtActProcessService;
import org.jeecgframework.designer.util.DesUtils;
import org.jeecgframework.designer.vo.AjaxJson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

/**
 * @ClassName: MockAPIController
 * @Description: 流程设计器（设计器首页所需数据API接口、接受设计器请求数据）
 * @author scott
 * @date 2010-03-12
 *
 */
@RestController("designerApiController")
@RequestMapping("/act/designer/api")
@Slf4j
//@RequestMapping("/designer/mock")
public class DesignerApiController {
	@Autowired
	private IExtActProcessService extActProcessService;
	@Autowired
	private IExtActProcessNodeService extActProcessNodeService;
	@Autowired
	private IExtActListenerService extActListenerService;
	@Autowired
	private IExtActExpressionService extActExpressionService;
	@Autowired
	private ISysBaseAPI sysBaseAPI;
	@Autowired
	@Lazy
	private RedisUtil redisUtil;

	/**
	 * 流程编辑
	 * 
	 * @param processId 流程ID
	 * @return
	 */
	@RequestMapping("/getProcessXml")
	@ResponseBody
	public void getProcessXml(HttpServletRequest request, HttpServletResponse response) {
		response.setContentType("text/xml;charset=UTF-8");
		String processId = oConvertUtils.getString(request.getParameter("processId"));
		String token = oConvertUtils.getString(request.getParameter("token"));
		log.info(" getProcessXml 登录令牌token： "+token);
        //校验 token 登录有效性
        TokenUtils.verifyToken(request, sysBaseAPI, redisUtil);

		ExtActProcess  process = extActProcessService.getById(processId);
		String retstr = null;
		try {
			retstr = StreamUtils.InputStreamTOString(StreamUtils.byteTOInputStream(process.getProcessXml()));
			response.getWriter().write(retstr);
		} catch (Exception e1) {
			e1.printStackTrace();
		}
	}

	/**
	 * 获取流程表达式列表
	 * 
	 * @return
	 */
	@RequestMapping(value = "/getExpressions", method = { RequestMethod.POST, RequestMethod.GET })
	public String getExpressions(HttpServletRequest request) {
		String token = oConvertUtils.getString(request.getParameter("token"));
		log.debug(" getExpressions 登录令牌token： "+token);
//		String jsonpath = "classpath:org/jeecgframework/designer/mock/getExpressions.json";
//		return StringUtil.readJson(jsonpath);
		List<ExtActExpression> list = extActExpressionService.list();
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("total", list.size());
		map.put("rows", list);
		JSONObject json = new JSONObject(map);
		log.info(json.toJSONString());
		return json.toJSONString();
	}

	/**
	 * 获取默认流程监听
	 * 
	 * @return
	 */
	@RequestMapping(value = "/getDefaultListener", method = { RequestMethod.POST, RequestMethod.GET })
	public String getDefaultListener(HttpServletRequest request) {
		String token = oConvertUtils.getString(request.getParameter("token"));
		log.debug(" getDefaultListener 登录令牌token： "+token);
		Map<String,Object> map = new HashMap<String,Object>();
		Map<String,Object> listenerObj = new HashMap<String,Object>();
		ExtActListener extActListener = extActListenerService.getById("402880e54803a496014805e5d9190012");
		if(extActListener!=null) {
			map.put("success", true);
			map.put("msg", "成功获取默认监听器！");
			listenerObj.put("id",extActListener.getId());
			listenerObj.put("listenername",extActListener.getListenerName());
			listenerObj.put("listenereven", extActListener.getListenerEvent());
			listenerObj.put("listenertype", extActListener.getListenerValueType());
			listenerObj.put("listenervalue", extActListener.getListenerValue());
		}else {
			map.put("success", false);
			map.put("msg", "获取默认监听器失败");
		}
		map.put("obj", listenerObj);
		JSONObject json = new JSONObject(map);
		log.info(json.toJSONString());
		return json.toJSONString();
//		String jsonpath = "classpath:org/jeecgframework/designer/mock/getDefaultListener.json";
//		return StringUtil.readJson(jsonpath);
	}

	/**
	 * 获取流程角色组列表（也叫用户组列表）
	 * 
	 * @return
	 */
	@RequestMapping(value = "/getGroups", method = { RequestMethod.POST, RequestMethod.GET })
	public String getGroups(HttpServletRequest request) {
		String token = oConvertUtils.getString(request.getParameter("token"));
		log.debug(" getGroups 登录令牌token： "+token);
		//TODO 有token风险
		List<RoleInfo> list = extActProcessService.getBpmRoles();
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("total", list.size());
		map.put("rows", list);
		JSONObject json = new JSONObject(map);
		log.info(json.toJSONString());
		return json.toJSONString();
		
//		String jsonpath = "classpath:org/jeecgframework/designer/mock/getGroups.json";
//		return StringUtil.readJson(jsonpath);
	}

	/**
	 * 获取流程用户列表
	 * 
	 * @return
	 */
	@RequestMapping(value = "/getUsers", method = { RequestMethod.POST, RequestMethod.GET })
	public String getUsers(HttpServletRequest request) {
		String token = oConvertUtils.getString(request.getParameter("token"));
		log.debug(" getUsers 登录令牌token： "+token);
		//TODO 有token风险
		List<UserInfo> list = extActProcessService.getBpmUsers();
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("total", list.size());
		map.put("rows", list);
		JSONObject json = new JSONObject(map);
		log.info(json.toJSONString());
		return json.toJSONString();
		
		//String jsonpath = "classpath:org/jeecgframework/designer/mock/getUsers.json";
		//return StringUtil.readJson(jsonpath);
	}

	/**
	 * 分页获取流程用户列表(popup分页列表)
	 *
	 * @return
	 */
	@RequestMapping(value = "/getPageUsers", method = { RequestMethod.POST, RequestMethod.GET })
	public String getPageUsers(HttpServletRequest request) {
		String token = oConvertUtils.getString(request.getParameter("token"));
		log.debug(" getPageUsers 登录令牌token： "+token);
		//TODO 有token风险
		Object pageNumber = request.getParameter("page"); //获取当前页码，easyui默认传到后台
		Object pageSize = request.getParameter("rows");   //获取每页显示多少行，easyui默认传到后台
		String account = request.getParameter("account"); //用户账号
		String name = request.getParameter("name"); 	  //用户昵称

		log.debug("pageNumber: "+ oConvertUtils.getInt(pageNumber,1));
		log.debug("pageSize: "+ oConvertUtils.getInt(pageSize,10));
		log.debug("account: "+ account);
		log.debug("name: "+ name);
		Page<UserInfo> page = new Page<UserInfo>(oConvertUtils.getInt(pageNumber,1), oConvertUtils.getInt(pageSize,10));
		Page<UserInfo> list = extActProcessService.getPageBpmUsers(account,name,page);
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("total", list.getTotal());
		map.put("rows", list.getRecords());
		JSONObject json = new JSONObject(map);
		log.info(json.toJSONString());
		return json.toJSONString();
	}

	/**
	 * 目前流程监听数据，不能通过解析xml直接获取数据，所以需要同步维护xml和表关系 1. 目前可以通过流程解析，获取到流程监听的 ids 2.
	 * 然后通过ids ，再获取到流程监听数据列表
	 * 
	 * @param id
	 * @return
	 * @return
	 */
	@RequestMapping("/getListenersByIds")
	public String getRealListenerGrid(HttpServletRequest request, HttpServletResponse response) {
		String token = oConvertUtils.getString(request.getParameter("token"));
		log.debug(" getRealListenerGrid 登录令牌token： "+token);
		//TODO 有token风险
		// 获取流程监听IDS
		String ids = oConvertUtils.getString(request.getParameter("ids"));
		String[] idsArr = ids.split(",");
		List<ListenerInfo> list = extActListenerService.getListenerInfoByIds(idsArr);
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("total", list.size());
		map.put("rows", list);
		JSONObject json = new JSONObject(map);
		log.info(json.toJSONString());
		return json.toJSONString();
		
//		return DesUtils.getMockDataRealListeners(ids);
	}

	/**
	 * 根据流程监听类型返回不同监听列表
	 * 
	 * @param id
	 * @return
	 * @return
	 */
	@RequestMapping("/getListenersByType")
	public String getListenersByType(HttpServletRequest request, HttpServletResponse response) {
		String token = oConvertUtils.getString(request.getParameter("token"));
		log.debug(" getListenersByType 登录令牌token： "+token);
		//TODO 有token风险
		// 获取流程监听IDS
		String typeid = oConvertUtils.getString(request.getParameter("typeid"));
		log.info(" 流程监听类型 typeid： " + typeid);
		List<ListenerInfo> list = extActListenerService.getListenerInfoByType(typeid);
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("total", list.size());
		map.put("rows", list);
		JSONObject json = new JSONObject(map);
		log.info(json.toJSONString());
		return json.toJSONString();
		// TODO
//		String jsonpath = "classpath:org/jeecgframework/designer/mock/listenersByType.json";
//		return StringUtil.readJson(jsonpath);

	}
	
	/**
	 * @return 导出流程
	 */
	@RequestMapping("/exportProcessDef")
	@ResponseBody
	public AjaxJson exportProcessDef(HttpServletRequest request, HttpServletResponse response) {
		String token = oConvertUtils.getString(request.getParameter("token"));
		log.debug(" exportProcessDef 登录令牌token： "+token);
		//TODO 有token风险
		AjaxJson j = new AjaxJson();
		String procdefId = oConvertUtils.getString(request.getParameter("procdefId"));
		String processName = oConvertUtils.getString(request.getParameter("processName"));
        LambdaQueryWrapper<ExtActProcess> queryWrapper = new LambdaQueryWrapper<ExtActProcess>();
        queryWrapper.eq(ExtActProcess::getProcessKey, procdefId);
		ExtActProcess tProcess = extActProcessService.getOne(queryWrapper);
//        String token = oConvertUtils.getString(request.getParameter("token"));
//        //校验 token 登录有效性
//        TokenUtils.verifyToken(request, sysBaseAPI, redisUtil);

		try {
			ByteArrayInputStream in = new ByteArrayInputStream(tProcess.getProcessXml());
			String filename = procdefId + ".bpmn20.xml";
            response.setContentType("application/octet-stream");
			response.setHeader("Content-Disposition", "attachment;filename=" + filename);
            IOUtils.copy(in, response.getOutputStream());
			response.flushBuffer();
			j.setMsg("导出成功!");
			in.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;

	}

	/**
	 * @return 保存流程
	 */
	@RequestMapping("/saveProcess")
	@ResponseBody
	public AjaxJson saveProcess(HttpServletRequest request) {
		String token = oConvertUtils.getString(request.getParameter("token"));
		log.debug(" exportProcessDef 登录令牌token： "+token);
		//TODO 有token风险
		AjaxJson j = new AjaxJson();
		try {
			j = extActProcessService.saveProcess(request);
		} catch (Exception e) {
			e.printStackTrace();
			j.setMsg(e.getMessage());
			j.setSuccess(false);
		}
		return j;
	}

}
